package demo1;

import Constant.constant;

import java.lang.invoke.ConstantBootstraps;

public class SingleLinkedList implements IList{
    static class ListNode{//定义一个静态内部类
        public int val;
        public ListNode next;

        //不用写next的构造方法
        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;

    public  void createLinkedList() {
        ListNode listNode0=new ListNode(10);
        ListNode listNode1=new ListNode(11);
        ListNode listNode2=new ListNode(12);
        ListNode listNode3=new ListNode(13);
        ListNode listNode4=new ListNode(14);
        listNode0.next=listNode1;
        listNode1.next=listNode2;
        listNode2.next=listNode3;
        listNode3.next=listNode4;
        //这是错误的：1.this.head没有初始化，默认为null 2.listNode0是局部变量，执行完后会销毁 3.这行代码的意思是listNode0指向null
//        listNode0=this.head;
        //正确写法 this.head指向listNode0
        this.head=listNode0;
    }


    @Override
    public void addFirst(int data) {
        ListNode listNode=new ListNode(data);
        listNode.next=head;
        head=listNode;
    }

    @Override
    public void addLast(int data) {
        ListNode listNode=new ListNode(data);
        //1.考虑链表是否为空
        if(head==null){
            head=listNode;
        }else{
            ListNode cur=head;
            while(cur.next!=null){
                cur=cur.next;
            }
            cur.next=listNode;
        }
    }

    @Override
    public void addIndex(int index, int data) {
        int len=size();
        if(index<0||index>len){
            String msg= constant.POS_is_WRONG;
            throw new posException(msg);
        }
        if(index==0){
            addFirst(data);
            len++;
            return;
        }
        if(index==len){
            addLast(data);
            len++;
            return;
        }
        //中间插入
        ListNode cur=head;
        while(index-1!=0){
            cur=cur.next;
            index--;
        }
        //先处理后面
        ListNode listNode=new ListNode(data);
        listNode.next=cur.next;
        cur.next=listNode;
    }

    @Override
    public boolean contains(int key) {
        ListNode cur=head;
        while(cur!=null){
            if(cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;

    }

    @Override
    public void remove(int key) {
        //1.考虑链表为空
        if(head==null){
            return;
        }
        //如果要删除第一个节点，需要单独考虑，因为findNodekey无法验证第一节点
        if(head.val==key){
            head=head.next;
            return;//必须要有return，一旦key等于头节点，删除完毕后，有return就直接结束remove方法了
        }
        //这个是要删除节点的前一个节点
        ListNode cur=findNodekey(key);
        if(cur==null){
            return;
        }
        ListNode del=cur.next;
        cur.next=del.next;
    }
    public ListNode findNodekey(int key){
        ListNode cur=head;
        while(cur.next!=null){
            if(cur.next.val==key){
                return cur;
            }
            cur=cur.next;
        }
        return null;

    }

    @Override
    public void removeAllKey(int key) {
        //1.考虑链表为空
        if(head==null){
            return;
        }
//        if(head.val==key){
//            head=head.next;
//        return;
//        }
        //写在这里不行，要写在最后
        ListNode pre=head;
        ListNode cur=head.next;
        //这个如果第一个节点也要删除，就不行了，所以第一个节点要单独讨论
        while(cur!=null){
            if(cur.val==key){
                pre.next=cur.next;
                cur=cur.next;
            }else{
                pre=cur;
                cur=cur.next;
            }
        }//这个代码完成后，已经删了除了第一个节点之外的所有关键字了
        if(head.val==key){
            head=head.next;
        }
    }

    @Override
    public int size() {
        int len=0;
        ListNode cur=head;
        while(cur!=null){
            len++;
            cur=cur.next;
        }
        return len;
    }

    @Override
    public void clear() {
        if(head==null){
            return;
        }
        ListNode cur=head;
        while(cur!=null){
            ListNode curN=cur.next;//保留下一个节点
            cur.next=null;//将本节点置为空
            cur=curN;
        }
        head=null;//这步不能少，防止外部代码仍可能通过 head 访问到已被"清空"的链表。

    }

    @Override
    public void display() {
        ListNode cur=head;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }
    public void display2(ListNode ret) {
        ListNode cur=ret;//可以从置顶的位置打印了
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }
//    public void reverseList(){
//        //1.考虑列表为空
//        if(head==null){
//            return;
//        }
//        ListNode cur=head.next;
//        head.next=null;
//        while(cur!=null){
//            ListNode curN=cur.next;//记录cur的下一个节点
//            cur.next=head;
//            head=cur;//是head指向cur，别写反了，通过调试看出来了
//            cur=curN;
//        }
//    }
public ListNode reverseList(){
    //1.考虑列表为空
    if(head==null){
        return head;
    }
    ListNode cur=head.next;
    head.next=null;
    while(cur!=null){
        ListNode curN=cur.next;//记录cur的下一个节点
        cur.next=head;
        head=cur;//是head指向cur，别写反了，通过调试看出来了
        cur=curN;
    }
    return head;
}
}
